package com.snake;

import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.os.Handler.Callback;
import android.os.Message;
import android.util.Size;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.common.GameBoard;

// 主活动
public class MainActivity extends Activity implements Callback, GameBoard.Callback, OnGestureListener {
    private ImageButton mButtonMusic;           // "播放音乐"按钮
    private ImageButton mButtonPause;           // "暂停"按钮
    private Game mGame;                         // 游戏
    private GestureDetector mGestureDetector;   // 手势事件检测器
    private TextView mLabelDifficulty;          // "难度"标签
    private TextView mLabelScore;               // "得分"标签

    /**
     * 自定义事件的响应方法。
     * @param message   事件
     * @return 事件在此被处理则返回 true，否则返回 false
     */
    @Override
    public boolean handleMessage(Message message) {
        switch (message.what) {
            case Const.UM_DIFFICULTY_UP:
                this.onDifficultyUp(message.arg1);
                return true;
            case Const.UM_GAME_OVER:
                this.onGameOver((Boolean)message.obj);
                return true;
            case Const.UM_SCORE:
                this.onScore(message.arg1);
                return true;
        }
        return false;
    }

    /**
     * "帮助"按钮的单击响应方法。
     * @param view  按钮
     */
    public void onButtonHelpClicked(View view) {
        if (mGame.getStatus() == Game.Status.PLAYING) {
            this.onButtonPauseClicked(null);
        }
        new AlertDialog.Builder(this).setMessage(R.string.IDS_HELP_TEXT).show();
    }

    /**
     * "播放音乐"按钮的单击响应方法。
     * @param view  按钮
     */
    public void onButtonMusicClicked(View view) {
        final boolean playingMusic = mGame.playMusic();
        mButtonMusic.setSelected(playingMusic);
    }

    /**
     * "暂停"按钮的单击响应方法。
     * @param view  按钮
     */
    public void onButtonPauseClicked(View view) {
        mGame.pause();
        mButtonPause.setSelected(mGame.getStatus() == Game.Status.PAUSED);
    }

    /**
     * "开始"按钮的单击响应方法。
     * @param view  按钮
     */
    public void onButtonStartClicked(View view) {
        // 游戏开始
        mGame.start();

        // 设置按钮状态
        mButtonPause.setEnabled(true);
        mButtonPause.setSelected(false);

        // 设置状态栏上的文字
        mLabelDifficulty.setText(super.getString(R.string.IDS_DIFFICULTY, 1));
        mLabelScore.setText(super.getString(R.string.IDS_SCORE, 0));
    }

    /**
     * 创建事件的响应方法。
     * @param savedInstanceState    保存的实例状态
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.activity_main);

        final GameBoard gameBoard = super.findViewById(R.id.IDC_GAME_BOARD);
        gameBoard.setCallback(this);
    }

    /**
     * 难度增加事件的响应方法。
     * @param difficulty    难度
     */
    private void onDifficultyUp(int difficulty) {
        final String text = super.getString(R.string.IDS_DIFFICULTY, difficulty);
        mLabelDifficulty.setText(text);
    }

    @Override
    public boolean onDown(@NonNull MotionEvent arg0) {
        return false;
    }

    /**
     * 滑动手势的响应方法。
     * @param e1        手势起点相关信息
     * @param e2        手势终点相关信息
     * @param velocityX 横向移动速度
     * @param velocityY 纵向移动速度
     * @return 事件在这个被处理，则返回 true，否则返回 false
     */
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        int direction;
        if (Math.abs(velocityX) > Math.abs(velocityY)) {
            if (velocityX < 0) {
                direction = Const.DIRECTION_LEFT;
            } else {
                direction = Const.DIRECTION_RIGHT;
            }
        } else {
            if (velocityY < 0) {
                direction = Const.DIRECTION_UP;
            } else {
                direction = Const.DIRECTION_DOWN;
            }
        }
        return mGame.onFling(direction);
    }

    /**
     * 游戏区域度量尺寸事件的响应方法。
     * @param gameBoard         游戏区域
     * @param widthMeasureSpec  父控件指定的宽度值
     * @param heightMeasureSpec 父控件指定的高度值
     * @return 游戏区域的尺寸
     */
    @Override
    public Size onGameBoardMeasure(View gameBoard, int widthMeasureSpec, int heightMeasureSpec) {
        // 获取可用的最大屏幕尺寸
        final int screenMaxWidth = View.MeasureSpec.getSize(widthMeasureSpec);
        final int screenMaxHeight = View.MeasureSpec.getSize(heightMeasureSpec);

        // 计算格的尺寸
        Const.GRID_SIZE = screenMaxWidth / Const.GAME_BOARD_GRID_COUNT_H;

        // 计算游戏区域尺寸
        final int width = Const.GRID_SIZE * Const.GAME_BOARD_GRID_COUNT_H;
        if (screenMaxHeight > 800) {
            Const.GAME_BOARD_GRID_COUNT_V = screenMaxHeight / Const.GRID_SIZE - 1;
        } else {
            Const.GAME_BOARD_GRID_COUNT_V = screenMaxHeight / Const.GRID_SIZE - 2;
        }
        final int height = Const.GAME_BOARD_GRID_COUNT_V * Const.GRID_SIZE;

        return new Size(width, height);
    }

    /**
     * 游戏结束事件的响应方法。
     * @param isWon 胜利则为 true，否则为 false
     */
    private void onGameOver(boolean isWon) {
        if (isWon) {
            Toast.makeText(this, R.string.IDS_WON, Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(this, R.string.IDS_LOST, Toast.LENGTH_LONG).show();
        }

        mButtonPause.setEnabled(false);
        mButtonPause.setSelected(false);
    }

    @Override
    public void onLongPress(@NonNull MotionEvent arg0) {
    }

    /**
     * 暂停事件的响应方法。
     */
    @Override
    public void onPause() {
        super.onPause();
        final Game.Status status = mGame.getStatus();
        if (status == Game.Status.PLAYING) {
            this.onButtonPauseClicked(null);
        }
    }

    /**
     * 得分事件的响应方法。
     * @param score 得分
     */
    private void onScore(int score) {
        final String text = super.getString(R.string.IDS_SCORE, score);
        mLabelScore.setText(text);
    }

    @Override
    public boolean onScroll(MotionEvent arg0, @NonNull MotionEvent arg1, float arg2, float arg3) {
        return false;
    }

    @Override
    public void onShowPress(@NonNull MotionEvent arg0) {
    }

    @Override
    public boolean onSingleTapUp(@NonNull MotionEvent arg0) {
        return false;
    }

    /**
     * 触屏事件的响应方法。
     * @param e 事件相关信息
     * @return 事件在此被处理则返回 true，否则返回 false
     */
    @Override
    public boolean onTouchEvent(MotionEvent e) {
        return mGestureDetector.onTouchEvent(e);
    }

    /**
     * 焦点变化事件的响应方法。
     * @param hasFocus  获得了焦点则为 true，否则为 false
     */
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (mGame == null) {
            // 初始化成员
            mButtonPause = super.findViewById(R.id.IDC_BUTTON_PAUSE);
            mButtonPause.setEnabled(false);
            mButtonMusic = super.findViewById(R.id.IDC_BUTTON_PLAY_MUSIC);
            mGestureDetector = new GestureDetector(this, this);
            mLabelDifficulty = super.findViewById(R.id.IDC_LABEL_DIFFICULTY);
            mLabelDifficulty.setText(super.getString(R.string.IDS_DIFFICULTY, 1));
            mLabelScore = super.findViewById(R.id.IDC_LABEL_SCORE);
            mLabelScore.setText(super.getString(R.string.IDS_SCORE, 0));

            // 创建游戏区域
            final GameBoard gameBoard = super.findViewById(R.id.IDC_GAME_BOARD);

            // 创建游戏
            mGame = new Game(this, gameBoard.getDrawer(), gameBoard);
        }
    }
}
